package house.service;

import com.alibaba.fastjson.JSONObject;
import house.entity.*;
import house.repository.DeviceRepository;
import house.repository.HousePicRepository;
import house.repository.HouseRepository;
import house.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class HouseService {

    @Autowired
    private HouseRepository houseRepository;

    @Autowired
    private HousePicRepository housePicRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DeviceRepository deviceRepository;

    public Res rent(Integer tenantId, Integer houseId) {
        User tenant = userRepository.findOne(tenantId);
        House house = houseRepository.findOne(houseId);
        house.getTenant().add(tenant);
        houseRepository.save(house);
        return new Res(200, "成功", house);
    }

    public Res finishRent(Integer tenantId, Integer houseId) {
        User tenant = userRepository.findOne(tenantId);
        House house = houseRepository.findOne(houseId);
        house.getTenant().remove(tenant);
        houseRepository.save(house);
        return new Res(200, "成功", house);
    }

    public Res saveHouse(House house) {
        houseRepository.save(house);
        return new Res(200, "成功", house);
    }

    public Res createHouse(House house, List<Device> devices, List<HousePic> pics) {
        houseRepository.save(house);
        for (Device device : devices) {
            device.setHouse(house);
            deviceRepository.save(device);
        }
        for (HousePic housePic : pics) {
            housePic.setHouse(house);
            housePicRepository.save(housePic);
        }
        return new Res(200, "成功", house);
    }

    public Res deleteHouse(Integer houseId) {
        houseRepository.delete(houseId);
        return new Res(200,"成功", null);
    }

    public Res filterHouse(House house, float area, float price) {
        List<House> houseList = houseRepository.findHousesByVillageContainsAndStyleContainsAndRegionContainsOrderByCreateDateDesc(house.getVillage(), house.getStyle(), house.getRegion());
        Predicate<House> p1;
        if (area == 0) {
            p1 = this::area0;
        } else if( area == 40) {
            p1 = this::area40;
        } else if (area == 80) {
            p1 = this::area80;
        } else if (area == 120){
            p1 = this::area120;
        } else {
            p1 = this::areaAll;
        }
        Predicate<House> p2;
        if (price == 0) {
            p2 = this::price0;
        } else if( price == 3000) {
            p2 = this::price3000;
        } else if (price == 5000) {
            p2 = this::price5000;
        } else if (price == 8000){
            p2 = this::price8000;
        } else {
            p2 = this::priveAll;
        }
        houseList = houseList.stream().filter(p1).filter(p2).collect(Collectors.toList());
        return new Res(200, "成功", houseList);
    }

    public Res findHouse(Integer houseId) {
        House house = houseRepository.findOne(houseId);
        house.setPics(housePicRepository.findAllByHouse(house));
        house.setDevices(deviceRepository.findAllByHouse(house));
        return new Res(200, "成功", house);
    }


    private boolean area0(House a) {
        return a.getArea() < 40;
    }

    private boolean area40(House a) {
        return a.getArea() >= 40 && a.getArea() < 80;
    }

    private boolean area80(House a) {
        return a.getArea() >= 80 && a.getArea() < 120;
    }

    private boolean area120(House a) {
        return a.getArea() >=120;
    }

    private boolean areaAll(House a) {
        return true;
    }

    private boolean price0(House a) {
        return a.getPrice() < 3000;
    }

    private boolean price3000(House a) {
        return a.getPrice() >= 3000 && a.getPrice() < 5000;
    }

    private boolean price5000(House a) {
        return a.getPrice() >= 5000 && a.getPrice() < 8000;
    }

    private boolean price8000(House a) {
        return a.getPrice() < 8000;
    }

    private boolean priveAll(House a) {
        return true;
    }
}
